import { app, BrowserWindow, ipcMain, Menu } from 'electron'
import { AxiosRequestConfig } from 'axios'
import log from 'electron-log'
import path from 'path'
import IPC from './ipc'
import Request from './http'
import Updater from './updater'

log.transports.console.level = 'silly'

console.log(import.meta.env)

function validateSender(frame: Electron.WebFrameMain) {
  const frameOrigin = new URL(frame.url)

  return frameOrigin.host === 'localhost'
}

class Loading implements AppView {
  public window: Electron.BrowserWindow
  constructor() {
    this.window = this.createLoading()
  }

  public createLoading() {
    const loading = new BrowserWindow({
      height: 300,
      width: 400,
      frame: false,
      transparent: true,
      resizable: false,
      skipTaskbar: true
    })

    const loadingPath = path.join(__dirname, './loading.html')
    loading.loadFile(loadingPath)

    return loading
  }
}

class Main<T extends AppView> {
  public window: Electron.BrowserWindow
  public loading: T
  public update: Updater
  constructor(view: T) {
    this.loading = view
    this.window = this.createWindow()
    this.update = new Updater(this.window!)

    this.createMenu()
    this.ipc()
  }

  public ipc() {
    ipcMain.on(IPC.OPEN_DEV_TOOLS, () => {
      this.window.webContents.openDevTools()
    })

    ipcMain.handle(IPC.REQUEST_HTTP, function (e, config: AxiosRequestConfig) {
      if (!validateSender(e.senderFrame)) return null

      console.log(config)
      return Request(config)
    })

    ipcMain.handle(IPC.REQUEST_HTTP_GET, function (e, config) {
      if (!validateSender(e.senderFrame)) return null
      return Request.get(config)
    })

    ipcMain.handle(IPC.REQUEST_HTTP_POST, function (e, config) {
      if (!validateSender(e.senderFrame)) return null
      return Request.post(config)
    })
  }

  public createWindow() {
    const self = this
    const window = new BrowserWindow({
      show: false,
      minWidth: 800,
      minHeight: 600,
      webPreferences: {
        devTools: true,
        preload: path.resolve(__dirname, '../middleware/main.js')
      }
    })

    window.once('ready-to-show', function () {
      setTimeout(() => {
        self.loading.window.hide()
        self.window.show()
        self.loading.window.close()
        self.loading.window.destroy()
      }, 3000)
    })

    window.once('show', () => {
      this.update.checkForUpdate()
    })

    if (app.isPackaged) {
      window.loadFile(path.resolve(__dirname, '../renderer/index.html'))
    } else {
      window.loadURL('http://localhost:9527')
    }

    return window
  }

  public createMenu() {
    const menu = Menu.buildFromTemplate([
      {
        label: '窗口',
        role: 'windowMenu',
        submenu: [
          {
            label: '重新加载',
            role: 'reload',
            click(menuItem, browserWindow, event) {
              browserWindow?.reload()
            }
          },
          {
            label: '开发者工具栏',
            role: 'toggleDevTools',
            click(menuItem, browserWindow, event) {
              browserWindow?.webContents.openDevTools()
            }
          },
          {
            label: '打印窗口',
            click(menuItem, browserWindow, event) {
              browserWindow?.webContents.printToPDF({ landscape: true })
            }
          }
        ]
      },
      {
        label: '关于',
        role: 'about',
        submenu: [
          {
            label: '检测升级',
            click: () => {
              ipcMain.emit('check:update')
              log.info('检测升级')
            }
          }
        ]
      }
    ])

    Menu.setApplicationMenu(menu)
  }
}

;(async function () {
  await app.whenReady()

  const loading = new Loading()
  new Main(loading)

  app.on('window-all-closed', function () {
    app.quit()
  })
})()
